// Minimal sample test file for `nrc test`.

func add(a int, b int) int {
    return a + b
}

func test_add() {
    assert(add(2, 3) == 5, "add(2, 3) should be 5")
}

func test_add_zero() {
    var x int = 42
    assert(add(x, 0) == x, "adding zero should keep value")
}

func test_add_negative() {
    assert(add(10, -3) == 7, "adding negative numbers should subtract")
}

func test_add_large_numbers() {
    assert(add(1000000, 2000000) == 3000000, "large numbers add correctly")
}

func test_add_associativity() {
    var a int = 5
    var b int = 7
    var c int = 11
    var left int = add(add(a, b), c)
    var right int = add(a, add(b, c))
    assert(left == right, "addition must be associative")
}

func test_add_commutativity() {
    var a int = 19
    var b int = -4
    assert(add(a, b) == add(b, a), "addition must be commutative")
}

func test_add_chain() {
    var total int = 0
    total = add(total, 1)
    total = add(total, 2)
    total = add(total, 3)
    total = add(total, 4)
    assert(total == 10, "chained additions should accumulate")
}

func test_add_mixed_signs() {
    assert(add(-20, 50) == 30, "mixed sign addition should work")
}

func test_add_increment() {
    var value int = 10
    value = add(value, 1)
    assert(value == 11, "increment using add should match ++")
}

func test_add_identity() {
    assert(add(0, 0) == 0, "0 + 0 must be zero")
    assert(add(-5, 5) == 0, "inverse numbers must cancel")
}

func test_add_stress() {
    var result int = 0
    var i int = 0
    while (i < 1000) {
        result = add(result, 1)
        i = i + 1
    }
    assert(result == 1000, "repeated adds should count accurately")
}

// Additional arithmetic operators
func test_int_subtraction_basic() {
    var result int = 10 - 3
    assert(result == 7, "10 - 3 should be 7")
}

func test_int_multiplication_basic() {
    var result int = 6 * 7
    assert(result == 42, "6 * 7 should be 42")
}

func test_int_division_basic() {
    var result int = 81 / 9
    assert(result == 9, "81 / 9 should be 9")
}

func test_int_modulo_basic() {
    var result int = 23 % 5
    assert(result == 3, "23 % 5 should be 3")
}

func test_int_unary_minus() {
    var value int = 12
    var negative int = -value
    assert(negative == -12, "unary minus should negate the value")
}

// Compound assignment operators
func test_add_assign_operator() {
    var total int = 3
    total += 9
    assert(total == 12, "total += 9 should yield 12")
}

func test_sub_assign_operator() {
    var total int = 12
    total -= 7
    assert(total == 5, "total -= 7 should yield 5")
}

func test_mul_assign_operator() {
    var total int = 5
    total *= 6
    assert(total == 30, "total *= 6 should yield 30")
}

func test_div_assign_operator() {
    var total int = 100
    total /= 4
    assert(total == 25, "total /= 4 should yield 25")
}

func test_mod_assign_operator() {
    var total int = 29
    total %= 5
    assert(total == 4, "total %= 5 should yield 4")
}

// Comparison operators
func test_less_than_operator() {
    var smaller bool = 3 < 9
    assert(smaller, "3 should be less than 9")
}

func test_greater_equal_operator() {
    var is_greater_or_equal bool = 10 >= 10
    assert(is_greater_or_equal, "10 should be greater than or equal to 10")
}

func test_not_equal_operator() {
    var different bool = 4 != 7
    assert(different, "4 should not equal 7")
}

func logical_rhs_should_not_run() bool {
    panic("logical RHS should not run")
    return false
}

func test_bool_and_operator() {
    var value bool = true && true
    assert(value, "true && true should be true")

    var short_circuit bool = false && logical_rhs_should_not_run()
    assert(!short_circuit, "false && rhs should not evaluate rhs")
}

func test_bool_or_operator() {
    var value bool = false || true
    assert(value, "false || true should be true")

    var short_circuit bool = true || logical_rhs_should_not_run()
    assert(short_circuit, "true || rhs should skip rhs evaluation")
}

func test_bool_not_operator() {
    var value bool = !false
    assert(value, "!false should be true")
}

func test_bool_equality_operator() {
    var left bool = true
    var right bool = false
    assert(left == true, "true should equal true")
    assert(left != right, "true should not equal false")
}

// Floating point arithmetic
func test_float32_multiplication() {
    var lhs float32 = 1.5
    var rhs float32 = 2.0
    var product float32 = lhs * rhs
    var expected float32 = 3.0
    assert(product == expected, "float32 multiplication should keep precision")
}

func test_float64_division() {
    var numerator float64 = 7.5
    var denominator float64 = 2.5
    var result float64 = numerator / denominator
    assert(result == 3.0, "7.5 / 2.5 should be 3.0")
}

func test_float32_addition() {
    var a float32 = 0.25
    var b float32 = 0.5
    var sum float32 = a + b
    assert(sum == 0.75, "float32 addition should be 0.75")
}

func test_float64_subtraction() {
    var a float64 = 1234.5
    var b float64 = 0.5
    var diff float64 = a - b
    assert(diff == 1234.0, "float64 subtraction should be 1234.0")
}

// Extended numeric types
func test_int64_arithmetic() {
    var a int64 = 3000000000
    var b int64 = 2000000000
    var sum int64 = a + b
    var expected int64 = 5000000000
    assert(sum == expected, "int64 addition should preserve high bits")
}

func test_uint_arithmetic() {
    var a uint = 40
    var b uint = 9
    var diff uint = a - b
    var expected uint = 31
    assert(diff == expected, "uint subtraction should stay unsigned")
}

func test_uint_multiplication_basic() {
    var a uint = 6
    var b uint = 7
    var product uint = a * b
    assert(product == 42, "uint multiplication should yield 42")
}

// Signed integer width coverage
func test_int8_arithmetic() {
    var a int8 = 100
    var b int8 = 27
    var diff int8 = a - b
    assert(diff == 73, "int8 subtraction should stay in range")
}

func test_int16_arithmetic() {
    var a int16 = 2000
    var b int16 = 1500
    var sum int16 = a + b
    assert(sum == 3500, "int16 addition should be 3500")
}

func test_int32_arithmetic() {
    var a int32 = 123456
    var b int32 = 65432
    var result int32 = a - b
    assert(result == 58024, "int32 subtraction should be 58024")
}

// Unsigned integer width coverage
func test_uint8_arithmetic() {
    var a uint8 = 120
    var b uint8 = 45
    var diff uint8 = a - b
    assert(diff == 75, "uint8 subtraction should be 75")
}

func test_uint16_arithmetic() {
    var a uint16 = 30000
    var b uint16 = 1234
    var diff uint16 = a - b
    assert(diff == 28766, "uint16 subtraction should be 28766")
}

func test_uint32_arithmetic() {
    var a uint32 = 2000000000
    var b uint32 = 123456789
    var diff uint32 = a - b
    assert(diff == 1876543211, "uint32 subtraction should be 1_876_543_211")
}

func test_uint64_arithmetic() {
    var a uint64 = 900000000000
    var b uint64 = 123456789
    var result uint64 = a + b
    assert(result == 900123456789, "uint64 addition should be 900123456789")
}

// Shift and bitwise operators
func test_left_shift_operator() {
    var value int = 1
    var shifted int = value << 3
    assert(shifted == 8, "1 << 3 should be 8")
}

func test_right_shift_operator() {
    var value int = 16
    var shifted int = value >> 2
    assert(shifted == 4, "16 >> 2 should be 4")
}

func test_bitwise_and_operator() {
    var result int = 12 & 10
    assert(result == 8, "12 & 10 should be 8")
}

func test_bitwise_or_operator() {
    var result int = 9 | 4
    assert(result == 13, "9 | 4 should be 13")
}

func test_bitwise_xor_operator() {
    var result int = 9 ^ 4
    assert(result == 13, "9 ^ 4 should be 13")
}

func test_bitwise_not_operator() {
    var value int = 5
    var inverted int = ~value
    assert(inverted == -6, "~5 should be -6 for signed ints")
}

// Other primitive types
func test_rune_arithmetic_basic() {
    var start rune = 65
    var result rune = start + 2
    assert(result == 67, "rune math should work like integers")
}

func test_rune_comparison_basic() {
    var alpha rune = 97
    var beta rune = 122
    assert(alpha < beta, "'a' rune should be less than 'z'")
}

func test_char_literal_basic() {
    var letter char = 'Z'
    var other char = 'A'
    assert(letter == 'Z', "char literal should preserve rune value")
    assert(letter != other, "different char literals should not match")
}

func test_string_concat_basic() {
    var hello String = "Hi"
    var world String = "NRC"
    var combined String = hello + " " + world
    assert(combined.len() == 6, "'Hi NRC' should have length 6")
}

func test_string_bytes_length_basic() {
    var chinese String = "你好"
    assert(chinese.len() == 2, "Chinese string should have 2 characters")
    assert(chinese.bytes_len() == 6, "Chinese string should have 6 bytes")
}
